package com.alibaba.cirtus.ots.application.app.ability.facade.v2serviceimpl;

import com.alibaba.acm.shaded.com.google.common.collect.Lists;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.lattice2.epoch.middleware.cache.runtime.service.EpochCacheService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.BaselineQueryScItemByPageFromDbRequest;
import com.epoch.app.bcorder.model.dto.QueryGoodsListForForecastSaleRequest;
import com.epoch.app.bcorder.model.dto.QueryGoodsListRequest;
import com.epoch.app.bcorder.model.dto.QueryGoodsListResponse;
import com.epoch.app.bcorder.model.dto.SearchStoreTerminalForPullRequest;
import com.epoch.app.bcorder.model.dto.WarehouseInfo;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.PlatformEnhanceService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.crplatformenhance.domain.customeraddress.dto.CustomerAddressLoadListRequest;
import com.epoch.app.crplatformenhance.domain.customeraddress.model.CustomerAddress;
import com.epoch.app.crplatformenhance.domain.customeraddress.service.CustomerAddressService;
import com.epoch.app.crplatformenhance.goodsfavorites.dto.QueryGoodsFavoritesRequest;
import com.epoch.app.crplatformenhance.goodsfavorites.model.GoodsFavorites;
import com.epoch.app.crplatformenhance.goodsfavorites.service.GoodsFavoritesService;
import com.epoch.app.crplatformenhance.model.dto.ScItemSDO;
import com.epoch.app.crunifiedinventory.model.dto.BusinessInventoryDTO;
import com.epoch.app.crunifiedinventory.model.dto.QueryStoreInventoryByPageRequest;
import com.epoch.app.crunifiedinventory.model.dto.SubmitStoreInventoryOrderRequest;
import com.epoch.app.crunifiedinventory.service.CrUnifiedInventoryService;
import com.epoch.app.crunifiedinventory.service.StoreStockService;
import com.epoch.app.otsapplicationappsdk.inventoryinput.dto.AsyncRequest;
import com.epoch.app.otsapplicationappsdk.inventoryinput.dto.InitRequest;
import com.epoch.app.otsapplicationappsdk.inventoryinput.dto.SubmitRequest;
import com.epoch.app.otsapplicationappsdk.inventoryinput.service.InventoryInputService;
import com.epoch.app.otsapplicationappsdk.model.dto.GoodsInfo;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Primary
@Component
public class InventoryInputV2ServiceImpl implements InventoryInputService {

    private static Log log = Log.getLogger(InventoryInputV2ServiceImpl.class);

    @Autowired
    private BaseDataService baseDataService;

    @Autowired
    private StoreStockService storeStockService;

    @Autowired
    private PlatformEnhanceService platformEnhanceService;

    @Autowired
    private UnifiedInventoryService unifiedInventoryService;
    @Autowired
    private CustomerAddressService customerAddressService;

    @Autowired
    private CrUnifiedInventoryService crUnifiedInventoryService;

    @Resource
    private GoodsFavoritesService favoritesService;

    @Resource(name="logsCheckSyncTaskExecutor")
    private ThreadPoolTaskExecutor taskExecutor;
    @Resource
    EpochCacheService epochCacheService;
    private static final String MINI_BASE_SCITEMS_KEY = "MINI_BASE_SCITEM_KEY";
    private static final String MINI_FAVORITE_USED_SCITEMS_KEY = "MINI_FAVORITE_USED_SCITEMS_KEY";
    private static final String FAVORITE_TAG = "收藏夹";
    private static final String USED_TAG = "近期使用";
    private static final String REDIS_CACHE_CODE = "ots_application_app_sdk:REDIS";
    private static long CACHE_TIME_OUT = 5 * 60L;


    private static final Integer MAX_PAGE_SIZE = 1000;
    private static final Integer MORE_MAX_PAGE_SIZE = 5000;

    @Override
    public Object init(InitRequest initRequest) {
        log.info("init_request:{}",JSON.toJSONString(initRequest));
        long st = System.currentTimeMillis();
        JSONObject result = new JSONObject();

        List goodsFavoritesList = new ArrayList();

        //当前用户收藏夹货品
        try {
            Result<List<GoodsFavorites>> listResult = favoritesService.queryGoodsFavorites(new QueryGoodsFavoritesRequest());
            if (Objects.nonNull(listResult)&& CollectionUtils.isNotEmpty(listResult.getResult())){
                GoodsFavorites goodsFavorites = listResult.getResult().get(0);
                JSONArray goodsList = JSONArray.parseArray(goodsFavorites.getGoodsList());
                if (CollectionUtils.isNotEmpty(goodsList)) {
                    for (Object goodsObj : goodsList) {
                        JSONObject goodsJson = (JSONObject) JSONObject.toJSON(goodsObj);
                        goodsFavoritesList.add(goodsJson.getString("goodsCode"));
                    }
                }
            }
        } catch (Exception e) {
            log.error("init_queryGoods_error",e);
        }

        try {
//            CompletableFuture<Result<List<QueryGoodsListResponse>>> queryGoodsFuture = CompletableFuture.supplyAsync(() -> {
//
////                //前端透传常用货品code，下发到接口返回常用货品类目
//                QueryGoodsListForForecastSaleRequest queryGoodsListForForecastSaleRequest = new QueryGoodsListForForecastSaleRequest();
//                queryGoodsListForForecastSaleRequest.setRecentlyUsedItemIdList(initRequest.getGoodsIdList());
//                if (CollectionUtils.isNotEmpty(goodsFavoritesList)) {
//                    queryGoodsListForForecastSaleRequest.setGoodsFavoritesList(goodsFavoritesList);
//                }
//                long start = System.currentTimeMillis();
//                log.info("queryGoodsListForForecastSale_request:{}",JSON.toJSONString(queryGoodsListForForecastSaleRequest));
//                Result<List<QueryGoodsListResponse>> listResult = platformEnhanceService.queryGoodsListForForecastSale(queryGoodsListForForecastSaleRequest);
//                log.info("queryGoodsListForForecastSale_result:{}",JSON.toJSONString(listResult));
////                Result<List<QueryGoodsListResponse>> listResult = queryGoodsList(initRequest.getGoodsIdList(),goodsFavoritesList);
//                log.info("init_queryGoods_cost:{}",System.currentTimeMillis() - start);
//                return listResult;
//            },taskExecutor);
            WarehouseInfo warehouseInfo = getDefaultStoreInfo();
            String id = warehouseInfo.getId();
//            CompletableFuture<WarehouseInfo> getWarehouseInfoFuture = CompletableFuture.supplyAsync(() -> {
//                try {
//                    return getDefaultStoreInfo();
//                } catch (Exception e) {
//                    return null;
//                }
//            },taskExecutor);
//            Result<List<QueryGoodsListResponse>> queryGoodsListResponse;
//            WarehouseInfo warehouseInfo;
//            String id;
//            try {
//                queryGoodsListResponse = queryGoodsFuture.get();
//                warehouseInfo = getWarehouseInfoFuture.get();
//                if (warehouseInfo == null){
//                    log.error("init_getWarehouseInfo_error");
//                    result.put("success", false);
//                    result.put("msg","未查到当前用户组织权限下的门店");
//                    log.info("init_cost:{}",System.currentTimeMillis() - st);
//                    return result;
//                }
//                id = warehouseInfo.getId();
//            }catch (Throwable e){
//                log.error("init_thread_error",e);
//                result.put("success", false);
//                result.put("msg","请求异常,请稍后重试");
//                log.info("init_cost:{}",System.currentTimeMillis() - st);
//                return result;
//            }
            //查询门店对应的客户送达方编码
            String receiveAddressCode="/";
            CompletableFuture<Result<List<CustomerAddress>>> queryCustomerAddressFuture = CompletableFuture.supplyAsync(() -> {
                CustomerAddressLoadListRequest customerAddressLoadListRequest = new CustomerAddressLoadListRequest();
                customerAddressLoadListRequest.setId(Long.parseLong(warehouseInfo.getAddressCode()));
                return customerAddressService.loadCustomerAddressList(customerAddressLoadListRequest);
            },taskExecutor);
//            CustomerAddressLoadListRequest customerAddressLoadListRequest = new CustomerAddressLoadListRequest();
//            customerAddressLoadListRequest.setId(Long.parseLong(warehouseInfo.getAddressCode()));
//            Result<List<CustomerAddress>> customerAddressList = customerAddressService.loadCustomerAddressList(customerAddressLoadListRequest);
//            log.info("init_loadCustomerAddressList_cost:{}",System.currentTimeMillis() - s);
//            if (Objects.nonNull(customerAddressList)&&CollectionUtils.isNotEmpty(customerAddressList.getResult())){
//                receiveAddressCode=receiveAddressCode+customerAddressList.getResult().get(0).getAddressCode();
//            }

//            QueryStoreInventoryByStoreRequest queryStoreInventoryByStoreRequest = new QueryStoreInventoryByStoreRequest();
//            queryStoreInventoryByStoreRequest.setStoreId(id);
            long start = System.currentTimeMillis();
            CompletableFuture<List<BusinessInventoryDTO>> storeInventoryFuture = CompletableFuture.supplyAsync(() -> {
                return queryStoreInventory(id);
            },taskExecutor);
            List<BusinessInventoryDTO> inventoryDTOList;
            Result<List<QueryGoodsListResponse>> queryGoodsListResponse;


            try{
                Result<List<CustomerAddress>> customerAddressList = queryCustomerAddressFuture.get();
                if (Objects.nonNull(customerAddressList)&&CollectionUtils.isNotEmpty(customerAddressList.getResult())){
                    receiveAddressCode=receiveAddressCode+customerAddressList.getResult().get(0).getAddressCode();
                }
                inventoryDTOList = storeInventoryFuture.get();
//                queryGoodsListResponse = queryGoodsFuture.get();
                queryGoodsListResponse = queryGoodsListResponse(initRequest.getGoodsIdList(),goodsFavoritesList);
            }catch (Throwable e){
                log.error("init_thread_error",e);
                result.put("success", false);
                result.put("msg","请求异常,请稍后重试");
                log.info("init_cost:{}",System.currentTimeMillis() - st);
                return result;
            }
            log.info("init_queryAddressAndStoreInventory_cost:{}",System.currentTimeMillis() - start);
            JSONArray realContent = new JSONArray();
            if (CollectionUtils.isNotEmpty(inventoryDTOList)){
                Set<String> scItemIds = inventoryDTOList.stream().map(BusinessInventoryDTO::getGoodsId).filter(StringUtils::isNotBlank)
                        .collect(Collectors.toSet());
                long startTime = System.currentTimeMillis();
                Map<String, ScItemSDO> scItemMap = getScItemMap(scItemIds);
                log.info("init_getScItem_cost:{}",System.currentTimeMillis() - startTime);
                for (BusinessInventoryDTO inventoryDTO : inventoryDTOList) {
                        JSONObject entry = JSONObject.parseObject(JSONObject.toJSONString(inventoryDTO));
                        Long totalQuantity = inventoryDTO.getTotalQuantity();
//                        String quantity = entry.getString("quantity");
                        String unit = inventoryDTO.getUnit();
                        Integer realId = entry.getInteger("id");
                        String dom = inventoryDTO.getDom();
                        entry.put("goodsCode",Optional.ofNullable(scItemMap.get(inventoryDTO.getGoodsId())).map(ScItemSDO::getOuterId).orElse(null));
                        entry.put("scItemId",inventoryDTO.getGoodsId());
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Date produceDate = format.parse(dom);
                        SimpleDateFormat chinaFormat=new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT+0800 (中国标准时间)'", Locale.US);
                        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy.M.d");

                        entry.put("saleUnitCode",unit);
                        entry.put("unit",convertUnit(unit));
                        entry.put("id",String.valueOf(realId));
                        entry.put("goodsNum",formatQuantity(totalQuantity));
                    entry.put("produceDate",simpleDateFormat.format(produceDate));
                    entry.put("produceDated",chinaFormat.format(produceDate));
                        realContent.add(entry);


                }
            }
            result.put("dataSource", realContent);
            result.put("selectedId", id);
            result.put("selectedValue", warehouseInfo.getName()+receiveAddressCode);

            result.put("DataResult", queryGoodsListResponse.getResult());
//            result.put("DataResult",buildGoodsList(queryGoodsListResponse.getResult(),initRequest.getGoodsIdList()));
            result.put("success", true);
        }catch (Exception e){
            result.put("success", false);
            result.put("msg",e.getMessage());
        }
        log.info("init_cost:{}",System.currentTimeMillis() - st);
        return result;
    }

    //取默认门店id
    private WarehouseInfo getDefaultStoreInfo() throws Exception{
        long start = System.currentTimeMillis();
        SearchStoreTerminalForPullRequest request = new SearchStoreTerminalForPullRequest();
        request.setModel(6);
        request.setLimit(1);
        log.info("unifiedInventoryService.wmsQueryStoreTerminalList$request:" + JSON.toJSONString(request));
        Result<List<WarehouseInfo>> response = unifiedInventoryService.searchStoreTerminalForPull(request);
        log.info("unifiedInventoryService.wmsQueryStoreTerminalList$response:" + JSON.toJSONString(response));
        if (response == null || CollectionUtils.isEmpty(response.getResult())) {
            throw new Exception("未查到当前用户组织权限下的门店");
        }
        log.info("getDefaultStoreInfo_cost:{}",System.currentTimeMillis() - start);
        return response.getResult().get(0);
    }

    //构造常用货品类目
    public List<QueryGoodsListResponse> buildGoodsList(List<QueryGoodsListResponse> queryGoodsList,List goodsIdList) {
        if (CollectionUtils.isEmpty(goodsIdList)) {
            return queryGoodsList;
        }
        if (CollectionUtils.isEmpty(queryGoodsList)) {
            return queryGoodsList;
        }
        Set<String> goodsIdSet = new HashSet();
        for (Object goodsId : goodsIdList) {
            goodsIdSet.add(goodsId.toString());
        }
        List list = new ArrayList();
        for (String goodsId : goodsIdSet) {
            boolean flg = false;
            for (QueryGoodsListResponse queryGoodsListResponse : queryGoodsList) {
                flg = false;
                if (CollectionUtils.isNotEmpty(queryGoodsListResponse.getGoodsList())) {
                    for (Object goodsObj : queryGoodsListResponse.getGoodsList()) {
                        JSONObject goodsJson = (JSONObject) JSONObject.toJSON(goodsObj);
                        if (goodsId.equals(goodsJson.getString("id"))) {
                            list.add(goodsObj);
                            flg = true;
                            break;
                        }
                    }
                }
                if (flg) break;
            }
        }
        if (CollectionUtils.isEmpty(list)) {
            return queryGoodsList;
        }
        QueryGoodsListResponse queryGoodsListResponse = new QueryGoodsListResponse();
        //端上构造的虚假常用货品类目,库中无该类目
        queryGoodsListResponse.setLabel("常用货品");
        queryGoodsListResponse.setGoodsList(list);

        List<QueryGoodsListResponse> queryGoodsListResponseList = new ArrayList<>();
        queryGoodsListResponseList.add(queryGoodsListResponse);
        queryGoodsListResponseList.addAll(queryGoodsList);

        return queryGoodsListResponseList;
    }

    @Override
    public Object submit(SubmitRequest submitRequest){
        JSONObject result = new JSONObject();
        try {
            JSONObject request = (JSONObject) JSONObject.toJSON(submitRequest.getAttr());
            log.info("input_submit$request:" + JSON.toJSONString(request));
            if (request != null && request.getString("fields") != null) {
                JSONArray dataArray = request.getJSONObject("fields").getJSONArray("dataSource");
                List dataList = buildDataList(dataArray);
                String storeId =  request.getJSONObject("fields").getString("selectedId");
                SubmitStoreInventoryOrderRequest submitStoreInventoryOrderRequest = new SubmitStoreInventoryOrderRequest();
                submitStoreInventoryOrderRequest.setStoreId(storeId);
                submitStoreInventoryOrderRequest.setRemark("");
                submitStoreInventoryOrderRequest.setDetailList(dataList);
                log.info("submitStoreInventoryOrder$request:" + JSON.toJSONString(submitStoreInventoryOrderRequest));
                Object object = storeStockService.submitStoreInventoryOrder(submitStoreInventoryOrderRequest);
                log.info("submitStoreInventoryOrder$response:" + JSON.toJSONString(object));
                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(object);
                result.put("success", jsonObject.getBoolean("success"));
                result.put("message", jsonObject.getString("message"));
                //提交请求还没有落库 跳转太快不能马上查询到门店库存
                Thread.sleep(2000);
            }
        }catch (Exception e){
            result.put("success", false);
            result.put("message", e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
    @Override
    public Object async(AsyncRequest asyncRequest) {
//        String s1 = epochCacheService.get("ots_application_app_sdk:REDIS", "111");
//        System.out.println(s1);
        log.info("async_request:{}",JSON.toJSONString(asyncRequest));
        long st = System.currentTimeMillis();
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(asyncRequest.getRequestInput()));

        String selectedId = jsonObject.getJSONObject("fields").getString("selectedId");
        String name = jsonObject.getJSONObject("fields").getString("value");


        JSONObject result = new JSONObject();

        List goodsFavoritesList = new ArrayList();

        //当前用户收藏夹货品
        try {
            long s = System.currentTimeMillis();
            Result<List<GoodsFavorites>> listResult = favoritesService.queryGoodsFavorites(new QueryGoodsFavoritesRequest());
            log.info("queryGoodsFavorites_cost:{}",System.currentTimeMillis() - s);
            if (Objects.nonNull(listResult)&& CollectionUtils.isNotEmpty(listResult.getResult())){
                GoodsFavorites goodsFavorites = listResult.getResult().get(0);
                JSONArray goodsList = JSONArray.parseArray(goodsFavorites.getGoodsList());
                if (CollectionUtils.isNotEmpty(goodsList)) {
                    for (Object goodsObj : goodsList) {
                        JSONObject goodsJson = (JSONObject) JSONObject.toJSON(goodsObj);
                        goodsFavoritesList.add(goodsJson.getString("goodsCode"));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            //查添加货品的货品/类目数据
//            CompletableFuture<Result<List<QueryGoodsListResponse>>> queryGoodsFuture = CompletableFuture.supplyAsync(() -> {
//                //前端透传常用货品code，下发到接口返回常用货品类目
//                QueryGoodsListForForecastSaleRequest queryGoodsListForForecastSaleRequest = new QueryGoodsListForForecastSaleRequest();
//                if (CollectionUtils.isNotEmpty(goodsFavoritesList)) {
//                    queryGoodsListForForecastSaleRequest.setGoodsFavoritesList(goodsFavoritesList);
//                }
//                Result<List<QueryGoodsListResponse>> listResult = platformEnhanceService.queryGoodsListForForecastSale(queryGoodsListForForecastSaleRequest);
////                return queryGoodsList(null,goodsFavoritesList);
//                return listResult;
//            },taskExecutor);
            long start = System.currentTimeMillis();
            CompletableFuture<List<BusinessInventoryDTO>> storeInventoryFuture = CompletableFuture.supplyAsync(() -> {
                return queryStoreInventory(selectedId);
            },taskExecutor);

            Result<List<QueryGoodsListResponse>> queryGoodsListResponse;
            List<BusinessInventoryDTO> inventoryDTOList;
            try {
                queryGoodsListResponse = queryGoodsList(null,goodsFavoritesList);
                inventoryDTOList = storeInventoryFuture.get();
            }catch (Throwable e){
                log.error("async_thread_error",e);
                result.put("success", false);
                result.put("msg","请求异常,请稍后重试");
                log.info("async_cost:{}",System.currentTimeMillis() - st);
                return result;
            }
            log.info("async_queryGoodsAndStoreInventory_cost:{}",System.currentTimeMillis() - start);

            JSONArray realContent = new JSONArray();
            if (CollectionUtils.isNotEmpty(inventoryDTOList)){
                Set<String> scItemIds = inventoryDTOList.stream().map(BusinessInventoryDTO::getGoodsId).filter(StringUtils::isNotBlank)
                        .collect(Collectors.toSet());
                long startTime = System.currentTimeMillis();
                Map<String, ScItemSDO> scItemMap = getScItemMap(scItemIds);
                log.info("async_getScItem_cost:{}",System.currentTimeMillis() - startTime);
                for (BusinessInventoryDTO inventoryDTO : inventoryDTOList) {
                    JSONObject entry = JSONObject.parseObject(JSONObject.toJSONString(inventoryDTO));
                    Long totalQuantity = inventoryDTO.getTotalQuantity();
                    String unit = inventoryDTO.getUnit();
                    Long realId = inventoryDTO.getId();
                    String dom = inventoryDTO.getDom();
                    entry.put("id",String.valueOf(realId));

                    entry.put("goodsCode",Optional.ofNullable(scItemMap.get(inventoryDTO.getGoodsId())).map(ScItemSDO::getOuterId).orElse(null));
                    entry.put("scItemId",inventoryDTO.getGoodsId());
                    entry.put("saleUnitCode",unit);
                    entry.put("unit",convertUnit(unit));
                    entry.put("goodsNum",formatQuantity(totalQuantity));
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date produceDate = format.parse(dom);
                    SimpleDateFormat chinaFormat=new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT+0800 (中国标准时间)'", Locale.US);
                    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy.M.d");
                    entry.put("produceDate",simpleDateFormat.format(produceDate));
                    entry.put("produceDated",chinaFormat.format(produceDate));
                    realContent.add(entry);
                }
                result.put("dataSource", realContent);
            }
            result.put("selectedId", selectedId);
            result.put("selectedValue", name);


            result.put("DataResult", queryGoodsListResponse.getResult());
//            result.put("DataResult",buildGoodsList(queryGoodsListResponse.getResult(),initRequest.getGoodsIdList()));
            result.put("success", true);
        }catch (Exception e){
            result.put("success", false);
            result.put("msg",e.getMessage());
        }
        log.info("async_cost:{}",System.currentTimeMillis() - st);
        return result;


    }

    private List buildDataList(JSONArray dataArray) throws Exception{
        Map<String,List<String>> checkMap = new HashMap<>();
        List result = new ArrayList();
        for (Object data : dataArray){
            JSONObject item = (JSONObject)JSONObject.toJSON(data);
            log.info("buildDataList_item" + JSON.toJSONString(item));
            log.info("buildDataList_checkMap" + JSON.toJSONString(checkMap));
            item.put("title", item.getString("goodsName"));
            item.put("quantity", item.getString("goodsNum"));
            item.put("scItemCode", item.getString("goodsCode"));
            item.put("produceDate", item.getString("produceDate").replace(".","-"));
            result.add(item);
            if (!checkMap.isEmpty() && CollectionUtils.isNotEmpty(checkMap.get(item.getString("scItemId")))&&  (checkMap.get(item.getString("scItemId")).contains((item.getString("produceDate")+"-"+item.getString("saleUnitCode"))))){
                throw new RuntimeException(item.getString("goodsName")+"_存在相同的生产日期_"+item.getString("produceDate")+"_存在相同的单位_"+item.getString("saleUnitCode"));
            }
            if (checkMap.containsKey(item.getString("scItemId"))){

                List<String> scItemId = checkMap.get(item.getString("scItemId"));
                scItemId.add(item.getString("produceDate")+"-"+item.getString("saleUnitCode"));
                checkMap.put(item.getString("scItemId"), scItemId);
                continue;

            }
            checkMap.put(item.getString("scItemId"), Lists.newArrayList(item.getString("produceDate")+"-"+item.getString("saleUnitCode")));
        }
        return result;
    }

    //分页查询门店库存数据
    private List<BusinessInventoryDTO> queryStoreInventory(String storeId){
        long st = System.currentTimeMillis();
        if (StringUtils.isBlank(storeId)){
            return null;
        }
        QueryStoreInventoryByPageRequest queryStoreInventoryByPageRequest = new QueryStoreInventoryByPageRequest();
        queryStoreInventoryByPageRequest.setWarehouseAreaId(storeId);
        queryStoreInventoryByPageRequest.setSize(MAX_PAGE_SIZE);
        Result<List<BusinessInventoryDTO>> listResult = crUnifiedInventoryService.queryStoreInventoryByPage(queryStoreInventoryByPageRequest);
        if (listResult == null || CollectionUtils.isEmpty(listResult.getResult())){
            return null;
        }
        List<BusinessInventoryDTO> inventories = listResult.getResult();
        int total = listResult.getTotal();
        if (total > MAX_PAGE_SIZE){
            int page = total % MAX_PAGE_SIZE == 0 ? total / MAX_PAGE_SIZE : total / MAX_PAGE_SIZE + 1;
            List<Future<List<BusinessInventoryDTO>>> futureList = Lists.newArrayList();
            for (int i =2;i<=page;i++){
                QueryStoreInventoryByPageRequest request = new QueryStoreInventoryByPageRequest();
                request.setWarehouseAreaId(storeId);
                request.setSize(MAX_PAGE_SIZE);
                request.setPage(i);
                CompletableFuture<List<BusinessInventoryDTO>> future = CompletableFuture.supplyAsync(() -> {
                    Result<List<BusinessInventoryDTO>> result = crUnifiedInventoryService.queryStoreInventoryByPage(request);
                    if (result == null || CollectionUtils.isEmpty(result.getResult())){
                        return null;
                    }
                    return result.getResult();
                },taskExecutor);
                futureList.add(future);
            }
            for (Future<List<BusinessInventoryDTO>> future : futureList) {
                try {
                    List<BusinessInventoryDTO> businessInventoryDTOS = future.get();
                    if (CollectionUtils.isNotEmpty(businessInventoryDTOS)){
                        log.info("inventory_size:{}",businessInventoryDTOS.size());
                        inventories.addAll(businessInventoryDTOS);
                    }
                } catch (Throwable e) {
                    log.error("queryStoreInventoryError",e);
                }

            }
        }
        log.info("queryStoreInventory_cost:{}",System.currentTimeMillis() - st);
        log.info("queryStoreInventory_size:{}",inventories.size());
        return inventories;
    }

    /**
     * 数量格式化
     * @param quantity
     * @return
     */
    private static String formatQuantity(Long quantity){
        if (quantity == null){
            return "0";
        }
        return new BigDecimal(quantity).movePointLeft(3).stripTrailingZeros().toPlainString();
    }
    /**
     * 批量根据货品id列表获取货品明细 走db
     * @param scItemIds
     * @return
     */
    private Map<String, ScItemSDO> getScItemMap(Set<String> scItemIds){
        Map<String,ScItemSDO> scItemSDOMap = Maps.newHashMap();
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(scItemIds)){
            return scItemSDOMap;
        }
        List<String> scItemIdList = new ArrayList<>(scItemIds);
        BaselineQueryScItemByPageFromDbRequest request = new BaselineQueryScItemByPageFromDbRequest();
        request.setIdList(scItemIdList);
        request.setLimit(scItemIdList.size() > MAX_PAGE_SIZE ? MORE_MAX_PAGE_SIZE: MAX_PAGE_SIZE);
        request.setStatusList(com.google.common.collect.Lists.newArrayList(1,-1));
        long start = System.currentTimeMillis();
        Object data = baseDataService.baselineQueryScItemByPageFromDb(request);
        log.info("async_queryScItem_cost:{}",System.currentTimeMillis() - start);
        List<ScItemSDO> scItemSDOS = convertResult2ScItemSDOList(data);
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(scItemSDOS)){
            scItemSDOMap = scItemSDOS.stream().collect(Collectors.toMap(ScItemSDO::getScItemId,a->a,(a,b)->a));
        }
        return scItemSDOMap;
    }
    /**
     * 中台货品转换
     * @param data
     * @return
     */
    private List<ScItemSDO> convertResult2ScItemSDOList(Object data){
        if (data == null){
            return null;
        }
        JSONObject object = JSON.parseObject(JSON.toJSONString(data));
        if (object == null){
            return null;
        }
        JSONObject result = object.getJSONObject("result");
        if (result == null){
            return null;
        }
        JSONObject resultJSONObject = result.getJSONObject("result");
        if (resultJSONObject == null){
            return null;
        }
        JSONArray content = resultJSONObject.getJSONArray("content");
        if (content == null || content.size() ==0){
            return null;
        }
        List<ScItemSDO> scItemSDOS = com.google.common.collect.Lists.newArrayList();
        for (int i = 0; i < content.size(); i++) {
            JSONObject jsonObject = content.getJSONObject(i);
            scItemSDOS.add(scItemConverter(jsonObject));
        }
        return scItemSDOS;
    }
    /**
     * 货品模型转换
     * **/
    private ScItemSDO scItemConverter(JSONObject obj) {
        ScItemSDO scItemSDO = new ScItemSDO();
        scItemSDO.setScItemId(obj.getString("scItemId"));
        scItemSDO.setOuterId(obj.getString("outerId"));
        scItemSDO.setTitle(obj.getString("title"));
        scItemSDO.setUnit(obj.getString("unit"));
        scItemSDO.setStatus(Objects.isNull(obj.getString("status")) ? -1 : Double.valueOf(obj.getString("status")).intValue());
        return scItemSDO;
    }
    private Result<List<QueryGoodsListResponse>>  queryGoodsList(List goodsIdList,List goodsFavoritesList){
        long st = System.currentTimeMillis();
        //基础的货品数据  收藏的货品数据  近期使用的货品数据
        //再创建一个喜欢的 收藏的货品合集 结合 基础 和收藏/近期使用 再加请求的.
        Result<List<QueryGoodsListResponse>> listResult;
        //是否需要重新请求
        String baseScItems = epochCacheService.get(REDIS_CACHE_CODE, MINI_BASE_SCITEMS_KEY);
        List<GoodsInfo> oldGoodsInfos = Lists.newArrayList();
        log.info("getBaseCache:{}",baseScItems);
        if (StringUtils.isNotBlank(baseScItems)){
            //转换成list
            if (CollectionUtils.isNotEmpty(goodsIdList) || CollectionUtils.isNotEmpty(goodsFavoritesList)){
                String favoriteAndUsedScItems = epochCacheService.get(REDIS_CACHE_CODE, MINI_FAVORITE_USED_SCITEMS_KEY);
                if (StringUtils.isNotBlank(favoriteAndUsedScItems)){
                    List<GoodsInfo> goodsInfos = JSON.parseArray(favoriteAndUsedScItems,GoodsInfo.class);
                    oldGoodsInfos = goodsInfos;
                    List<GoodsInfo> sameGoodsInfos = goodsInfos.stream().filter(x -> {
                        boolean hasUsed = CollectionUtils.isEmpty(goodsIdList) ? false : goodsIdList.contains(x.getGoodsCode());
                        boolean hasFavorite = CollectionUtils.isEmpty(goodsFavoritesList) ? false : goodsFavoritesList.contains(x.getGoodsCode());
                        return hasUsed || hasFavorite;
                    }).collect(Collectors.toList());
//                    Object collect = goodsIdList.stream().filter(x -> !sameGoodsInfos.stream().anyMatch(y -> y.getGoodsCode().equals(x))).collect(Collectors.toList());
//                    log.info("xx:{}",JSON.toJSONString(collect));
                    Integer goodsFavoritesListSize = Optional.ofNullable(goodsFavoritesList).map(List::size).orElse(0);
                    Integer goodsIdListSize = Optional.ofNullable(goodsIdList).map(List::size).orElse(0);
                    //获取合集数量
                    long sumCount = Stream.of(Optional.ofNullable(goodsFavoritesList).orElse(Lists.newArrayList()),
                                    Optional.ofNullable(goodsIdList).orElse(Lists.newArrayList()))
                            .filter(org.apache.commons.collections4.CollectionUtils::isNotEmpty)
                            .flatMap(Collection::stream)
                            .distinct()
                            .count();
                    Integer sameSize = Optional.ofNullable(sameGoodsInfos).map(List::size).orElse(0);
                    if (sameSize >= sumCount){
//                        listResult = JSON.parseObject(baseScItems,Result.class);
                        listResult = JSON.parseObject(baseScItems,new TypeReference<Result<List<QueryGoodsListResponse>>>(){});
                        if (goodsFavoritesListSize > 0){
                            for (QueryGoodsListResponse response : listResult.getResult()) {
                                if (FAVORITE_TAG.equals(response.getLabel())){
                                    response.setGoodsList(sameGoodsInfos.stream()
                                            .filter(goodsInfo -> goodsFavoritesList.contains(goodsInfo.getGoodsCode())).collect(Collectors.toList()));
                                    break;
                                }
                            }
                        }
                        if (goodsIdListSize > 0){
                            for (QueryGoodsListResponse response : listResult.getResult()) {
                                if (USED_TAG.equals(response.getLabel())){
                                    response.setGoodsList(sameGoodsInfos.stream()
                                            .filter(goodsInfo -> goodsIdList.contains(goodsInfo.getGoodsCode())).collect(Collectors.toList()));
                                    break;
                                }
                            }
                        }
                        log.info("queryGoodsCache_cost:{}",System.currentTimeMillis() - st);
                        return listResult;
                    }

                }
            }else {
                listResult = JSON.parseObject(baseScItems,Result.class);
                log.info("queryGoodsCache_cost:{}",System.currentTimeMillis() - st);
                return listResult;
            }
        }
        //判断喜欢和近期使用的是否在其中 如果不在其中直接就重新请求



        //前端透传常用货品code，下发到接口返回常用货品类目
        QueryGoodsListRequest queryGoodsListRequest = new QueryGoodsListRequest();
        queryGoodsListRequest.setRecentlyUsedItemIdList(goodsIdList);
        if (CollectionUtils.isNotEmpty(goodsFavoritesList)) {
            queryGoodsListRequest.setGoodsFavoritesList(goodsFavoritesList);
        }
        long start = System.currentTimeMillis();
        listResult = platformEnhanceService.queryGoodsList(queryGoodsListRequest);
        log.info("queryGoods_cost:{}",System.currentTimeMillis() - start);
        //获取其中近期使用 和喜欢的
        if (listResult != null && CollectionUtils.isNotEmpty(listResult.getResult())){
            //获取所有的货品
            long count = listResult.getResult().stream().map(QueryGoodsListResponse::getGoodsList).flatMap(Collection::stream).count();
            List<GoodsInfo> favoriteAndUsedList =  Lists.newArrayList();
            for (QueryGoodsListResponse response : listResult.getResult()) {
                favoriteAndUsedList.addAll(JSON.parseArray(JSON.toJSONString(response.getGoodsList()),GoodsInfo.class));
            }
            for (QueryGoodsListResponse queryGoodsListResponse : listResult.getResult()) {
                if (FAVORITE_TAG.equals(queryGoodsListResponse.getLabel()) || USED_TAG.equals(queryGoodsListResponse.getLabel())){
                    queryGoodsListResponse.setGoodsList(Lists.newArrayList());
                }
            }
            boolean setSuccess = epochCacheService.setnx(REDIS_CACHE_CODE, MINI_BASE_SCITEMS_KEY, JSON.toJSONString(listResult));
            if (setSuccess){
                epochCacheService.expire(REDIS_CACHE_CODE,MINI_BASE_SCITEMS_KEY,CACHE_TIME_OUT, TimeUnit.SECONDS);
                if (CollectionUtils.isNotEmpty(favoriteAndUsedList)){
                    if (CollectionUtils.isNotEmpty(oldGoodsInfos)){
                        favoriteAndUsedList.addAll(oldGoodsInfos);
                    }
                    favoriteAndUsedList = favoriteAndUsedList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                            () -> new TreeSet<>(Comparator.comparing(GoodsInfo::getGoodsCode).reversed())
                    ),ArrayList::new));
                    setSuccess = epochCacheService.setnx(REDIS_CACHE_CODE,MINI_FAVORITE_USED_SCITEMS_KEY,JSON.toJSONString(favoriteAndUsedList));
                    if (setSuccess){
                        epochCacheService.expire(REDIS_CACHE_CODE,MINI_FAVORITE_USED_SCITEMS_KEY,CACHE_TIME_OUT,TimeUnit.SECONDS);
                    }
                }
            }
        }
        log.info("queryGoodsList_cost:{}",System.currentTimeMillis() - st);
        return listResult;
    }

    private static String convertUnit(String unit){
        if ("PC".equalsIgnoreCase(unit)){
            return "件";
        }else if ("TO".equalsIgnoreCase(unit)){
            return "吨";
        }else if ("KG".equalsIgnoreCase(unit)){
            return "千克";
        }else if ("HE".equalsIgnoreCase(unit)){
            return "盒";
        }else if ("ZHA".equalsIgnoreCase(unit)){
            return "张";
        }else if ("EA".equalsIgnoreCase(unit)){
            return "个";
        }else if ("KUA".equalsIgnoreCase(unit)){
            return "块";
        }else if ("PAK".equalsIgnoreCase(unit)){
            return "Pack";
        }else if ("BOT".equalsIgnoreCase(unit)){
            return "瓶";
        }else if ("KAN".equalsIgnoreCase(unit)){
            return "听";
        }else if ("BAG".equalsIgnoreCase(unit)){
            return "袋";
        }else if ("TNG".equalsIgnoreCase(unit)){
            return "桶";
        }else if ("BEI".equalsIgnoreCase(unit)){
            return "杯";
        }else if ("GUA".equalsIgnoreCase(unit)){
            return "罐";
        }else if ("BEI".equalsIgnoreCase(unit)){
            return "杯";
        }else if ("M3".equalsIgnoreCase(unit)){
            return "立方米";
        }else if ("KB".equals(unit)){
            return "千包";
        }else if ("ZU".equalsIgnoreCase(unit)){
            return "组";
        }else if ("PAC".equalsIgnoreCase(unit)){
            return "包";
        }else if ("KAR".equalsIgnoreCase(unit)){
            return "纸板箱";
        }
        return unit;
    }

    public Result<List<QueryGoodsListResponse>> queryGoodsListResponse(List goodsIdList,List goodsFavoritesList){
        QueryGoodsListForForecastSaleRequest queryGoodsListForForecastSaleRequest = new QueryGoodsListForForecastSaleRequest();
        queryGoodsListForForecastSaleRequest.setRecentlyUsedItemIdList(goodsIdList);
        if (CollectionUtils.isNotEmpty(goodsFavoritesList)) {
            queryGoodsListForForecastSaleRequest.setGoodsFavoritesList(goodsFavoritesList);
        }
        long start = System.currentTimeMillis();
        log.info("queryGoodsListForForecastSale_request:{}",JSON.toJSONString(queryGoodsListForForecastSaleRequest));
        Result<List<QueryGoodsListResponse>> listResult = platformEnhanceService.queryGoodsListForForecastSale(queryGoodsListForForecastSaleRequest);
        log.info("queryGoodsListForForecastSale_result:{}",JSON.toJSONString(listResult));
//                Result<List<QueryGoodsListResponse>> listResult = queryGoodsList(initRequest.getGoodsIdList(),goodsFavoritesList);
        log.info("init_queryGoods_cost:{}",System.currentTimeMillis() - start);
        return listResult;
    }
}
